package com.qianxx.viewlibrary.progress.arc;

import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.animation.PropertyValuesHolder;
import android.animation.TimeInterpolator;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.RectF;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.View;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.BounceInterpolator;
import android.view.animation.DecelerateInterpolator;

public class ArcProgress extends View {
    private float progress;
    //进度条前景颜色
    private int fontColor = Color.BLACK;
    //进度条背景颜色
    private int backgroundColor = Color.TRANSPARENT;
    //进度条宽度
    private int strokeWidth = 8;
    //动画持续时间
    private long duration = 2000;
    //是否显示文本
    private boolean isShowText = true;
    //字体大小
    private float textSize;
    //是否是平底开口的进度条
    private boolean isFlatBottom;
    //画笔
    Paint paint = new Paint();

    //动画加速器
    private TimeInterpolator interpolator = new BounceInterpolator();

    public ArcProgress(Context context) {
        this(context, null);
    }

    public ArcProgress(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public ArcProgress(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int width = MeasureSpec.getSize(widthMeasureSpec);
        int height = MeasureSpec.getSize(heightMeasureSpec);
        textSize = width < height ? width / 7 : height / 7;
    }

    public float getProgress() {
        return progress;
    }

    public void setProgress(float progress) {
        this.progress = progress;
        invalidate();
    }

    public int getFontColor() {
        return fontColor;
    }

    public void setFontColor(int fontColor) {
        this.fontColor = fontColor;
    }

    public int getStrokeWidth() {
        return strokeWidth;
    }

    public void setStrokeWidth(int strokeWidth) {
        this.strokeWidth = strokeWidth;
    }

    public long getDuration() {
        return duration;
    }

    public void setDuration(long duration) {
        this.duration = duration;
    }

    public TimeInterpolator getInterpolator() {
        return interpolator;
    }

    public void setInterpolator(TimeInterpolator interpolator) {
        this.interpolator = interpolator;
    }

    public boolean isShowText() {
        return isShowText;
    }

    public void setShowText(boolean showText) {
        isShowText = showText;
    }

    public float getTextSize() {
        return textSize;
    }

    public void setTextSize(float textSize) {
        this.textSize = textSize;
    }

    public boolean isFlatBottom() {
        return isFlatBottom;
    }

    public void setFlatBottom(boolean flatBottom) {
        isFlatBottom = flatBottom;
    }

    public int getBackgroundColor() {
        return backgroundColor;
    }

    @Override
    public void setBackgroundColor(int backgroundColor) {
        this.backgroundColor = backgroundColor;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        RectF rectF = new RectF(strokeWidth, strokeWidth,
                getWidth() - strokeWidth, getHeight() - strokeWidth);

        paint.setStyle(Paint.Style.STROKE);
        paint.setAntiAlias(true);
        paint.setStrokeCap(Paint.Cap.ROUND);
        paint.setStrokeWidth(strokeWidth);
        if (isFlatBottom()) {
            paint.setColor(backgroundColor);
            canvas.drawArc(rectF, 135, 270f, false, paint);
            paint.setColor(fontColor);
            canvas.drawArc(rectF, 135, progress * 2.7f, false, paint);
        } else {
            paint.setColor(backgroundColor);
            canvas.drawArc(rectF, 90, 360f, false, paint);
            paint.setColor(fontColor);
            canvas.drawArc(rectF, 90, progress * 3.6f, false, paint);
        }
        if (!isShowText())
            return;

        paint.setStyle(Paint.Style.FILL);
        paint.setColor(fontColor);
        paint.setAntiAlias(true);
        paint.setTextSize(textSize);
        String text = (int) progress + "";
        canvas.drawText(text + "", (getWidth() - getTextWidth(text)) / 2, (getHeight() + getTextHeight(text)) / 2, paint);
    }

    private int getTextWidth(String text) {
        Rect rect = new Rect();
        paint.getTextBounds(text, 0, text.length(), rect);
        return rect.width();
    }

    private int getTextHeight(String text) {
        Rect rect = new Rect();
        paint.getTextBounds(text, 0, text.length(), rect);
        return rect.height();
    }

    public void startAnimation() {
        ObjectAnimator progress = ObjectAnimator.ofFloat(this, "progress", 0, 100);
        progress.setInterpolator(interpolator);
        progress.setDuration(duration * 5 / 7);

        PropertyValuesHolder holder1 = PropertyValuesHolder.ofFloat("scaleX", 1, 1.1f);
        PropertyValuesHolder holder2 = PropertyValuesHolder.ofFloat("scaleY", 1, 1.1f);
        ObjectAnimator scale1 = ObjectAnimator.ofPropertyValuesHolder(this, holder1, holder2);
        scale1.setInterpolator(new AccelerateInterpolator());
        scale1.setDuration(duration / 7);

        PropertyValuesHolder holder3 = PropertyValuesHolder.ofFloat("scaleX", 1.1f, 1f);
        PropertyValuesHolder holder4 = PropertyValuesHolder.ofFloat("scaleY", 1.1f, 1f);
        ObjectAnimator scale2 = ObjectAnimator.ofPropertyValuesHolder(this, holder3, holder4);
        scale2.setInterpolator(new DecelerateInterpolator());
        scale2.setDuration(duration / 7);

        AnimatorSet animatorSet = new AnimatorSet();
        if (isFlatBottom())
            animatorSet.playSequentially(progress);
        else
            animatorSet.playSequentially(progress, scale1, scale2);
        animatorSet.start();
    }
}
